#define PI 3.14159265

#ifdef D3D9_IMPL

#else    

#define D3D10_CULL_NONE		1
#define D3D10_CULL_FRONT	2
#define D3D10_CULL_BACK		3

#define D3D10_BLEND_ZERO 1
#define D3D10_BLEND_ONE 2
#define D3D10_BLEND_SRC_COLOR 3
#define D3D10_BLEND_INV_SRC_COLOR 4
#define D3D10_BLEND_SRC_ALPHA 5
#define D3D10_BLEND_INV_SRC_ALPHA 6
#define D3D10_BLEND_DEST_ALPHA 7
#define D3D10_BLEND_INV_DEST_ALPHA 8
#define D3D10_BLEND_DEST_COLOR 9
#define D3D10_BLEND_INV_DEST_COLOR 10
#define D3D10_BLEND_SRC_ALPHA_SAT 11
#define D3D10_BLEND_BLEND_FACTOR 14
#define D3D10_BLEND_INV_BLEND_FACTOR 15
#define D3D10_BLEND_SRC1_COLOR 16
#define D3D10_BLEND_INV_SRC1_COLOR 17
#define D3D10_BLEND_SRC1_ALPHA 18
#define D3D10_BLEND_INV_SRC1_ALPHA 19
#endif

#ifndef LIB_STANDARD_FXH
#define LIB_STANDARD_FXH


Texture2D g_tex0;
sampler2D g_sam0 = sampler_state
{
	texture = g_tex0;
	Filter = MIN_MAG_MIP_LINEAR;
	AddressU = WRAP;
	AddressV = WRAP;
};

Texture2D g_tex1;
sampler2D g_sam1 = sampler_state
{
	texture= g_tex1;
	Filter = MIN_MAG_MIP_LINEAR;
	AddressU = WRAP;
	AddressV = WRAP;
};

Texture2D g_tex2;
sampler2D g_sam2 = sampler_state
{
	texture= g_tex2;
	Filter = MIN_MAG_MIP_LINEAR;
	AddressU = WRAP;
	AddressV = WRAP;
};

Texture2D g_tex3;
sampler2D g_sam3 = sampler_state
{
	texture= g_tex3;
	Filter = MIN_MAG_MIP_POINT;
	AddressU = WRAP;
	AddressV = WRAP;
};

//Sampler unit 0
float3 Texture_Unit0(float3 uvw) {

	return (float3)tex2D(g_sam0,uvw.xy);
}

//Sampler unit 1
float3 Texture_Unit1(float3 uvw) {

	return (float3)tex2D(g_sam1,uvw.xy);
}

//Sampler unit 2
float3 Texture_Unit2(float3 uvw) {

	return (float3)tex2D(g_sam2,uvw.xy);
}

//Sampler for procedural base data
float3 Texture_BaseData(float2 uv) {

	return (float3)tex2Dlod(g_sam3,float4(uv,0,0));
}

struct DirLight {
	float3 direction;
	float3 ambientColor;
	float3 diffuseColor;
	float3 specularColor;
	float ambientCoeff;
	float diffuseCoeff;
	float specularCoeff;
	float multiplier;
};

#define DEFAULT_DIRLIGHT {{0.0f,-1.0f,0.0f}, \
						{0.0015f,0.0015f,0.0015f},{0.58f,0.54f,0.54f},{0.69f,0.693f,0.63f}, \
						1.0f,1.0f,1.0f, \
						1.0f}

#ifdef D3D9_IMPL
float4x4 ViewProj;
float3 ViewPosition;
float4x4 World;
float LightFactor = 0.0f;
DirLight dlight0 = DEFAULT_DIRLIGHT;
float Time = 0.0f;
#else



cbuffer cbPerFrame {
	float4x4 ViewProj;
	float3 ViewPosition;
	float4x4 World;
	float Time;
	float LightFactor = 0.0f;
	DirLight dlight0 = DEFAULT_DIRLIGHT;
};
#endif


float3 ComputeDirLighting(float3 wsNormal, float3 wsPosition, float specularScale, DirLight light) {

	float3 d = normalize(-light.direction);
	float3 n = normalize(wsNormal);

	float3 eyeToPosition = normalize(ViewPosition - wsPosition);
	float3 halfSpecular = normalize((eyeToPosition + d) * 0.5f);
	
	float specular = pow( max(0.0f, dot(n, halfSpecular)), 80.0f) * specularScale;
	float diffusion = max(0.0f,dot(n, d));

	float3 lightComputation = 
	((light.ambientColor * light.ambientCoeff) + 
	(diffusion * light.diffuseColor * light.diffuseCoeff) + 
	(specular * light.specularColor * light.specularCoeff)) * light.multiplier;

	return lightComputation;
}


#ifdef D3D9_IMPL
#else
RasterizerState DefaultRasterize
{ 
    CULLMODE = D3D10_CULL_NONE;
	FillMode = SOLID;
};

BlendState DefaultBlend
{ 
    BlendEnable[0] = True;
    SrcBlend = D3D10_BLEND_SRC_ALPHA;
    DestBlend = D3D10_BLEND_INV_SRC_ALPHA;
};

DepthStencilState DefaultDepthStencil
{ 
DepthEnable = TRUE;
DepthWriteMask = ALL;
DepthFunc = LESS_EQUAL;
    
    StencilEnable = False;
};
#endif


#endif
